import type { AdjustElementStyleConfig } from '../../../../lib/abstract'
import type {
  BaseStyleConfig,
  IPersonalizationItemConfig,
} from '../../../../types/interfaces'
import { StyleEditor } from '../../../../components/style_editor'
import { UserPref } from '../../../../lib/abstract'
import { createStandardStyleTag } from '../../../../lib/style_injector'
import { VALID_RESULT } from '../../../../types/constants'

interface ConvertCSSOptions {
  /**
   * 是否添加!important标记
   * @default false
   */
  addImportant?: boolean

  /**
   * 是否包含元数据注释
   * @default true
   */
  includeComments?: boolean

  /**
   * 自定义注释格式器
   * @param meta 样式元数据
   */
  commentFormatter?: (meta: AdjustElementStyleConfig) => string
}

export class StyleAdjust extends UserPref {
  readonly id = 'style_adjust'
  readonly name = 'StyleAdjust'
  readonly styleConfigKey = 'styleAdjust'
  readonly cssProperty = ''
  readonly cssValueSuffix = ''
  private styles: AdjustElementStyleConfig[] | undefined = undefined

  constructor(config: IPersonalizationItemConfig) {
    super(config)
  }

  createComponent(config: BaseStyleConfig, _value: string, _mode: string, _debouncedSave: (() => void) & { flush: () => void }): StyleEditor {
    const id = this.generateId(config.styleVar)
    return new StyleEditor({
      id,
      targetSelector: '',
      label: '样式调整',
      onStyleChange(_selector: string, _styles: Record<string, string>): void {
      },
      onGenerated: (styles: AdjustElementStyleConfig[]) => {
        this.styles = styles
      },
    })
  }

  handleCheck(value: string): { status: ValidResultType, error: string } {
    if (!value || value.length === 0)
      return { status: VALID_RESULT.SKIP.value, error: '' }
    return { status: VALID_RESULT.VALID.value, error: '' }
  }

  /**
   * 确保CSS值以分号结尾
   * @param value - 需要检查的 CSS 属性值
   * @returns 保证以分号结尾的值
   * @example
   * ensureSemicolon('color: red') // 返回 'color: red;'
   */
  ensureSemicolon(value: string): string {
    return value.trim().endsWith(';') ? value : `${value};`
  }

  /**
   * 转义CSS选择器中的特殊字符
   * @param selector - 原始 CSS 选择器
   * @returns 转义后的安全选择器
   * @example
   * escapeSelector('a[href="test"]') // 返回 'a[href=\"test\"]'
   */
  escapeSelector(selector: string): string {
    return selector.replace(/"/g, '\\"')
  }

  /**
   * 对CSS属性按字母顺序排序
   * @param properties - 需要排序的 CSS 属性键值对
   * @returns 排序后的属性数组
   * @example
   * sortCSSProperties({ 'z-index': '1', 'color': 'red' })
   * // 返回 [['color', 'red'], ['z-index', '1']]
   */
  sortCSSProperties(properties: Record<string, string>): [string, string][] {
    return Object.entries(properties).sort(([a], [b]) => a.localeCompare(b))
  }

  /**
   * 将样式配置数组转换为格式化的CSS字符串
   * @param styles - 样式配置数组
   * @param options - 转换选项
   * @param options.addImportant - 是否添加!important标记 (默认false)
   * @param options.includeComments - 是否包含注释 (默认true)
   * @returns 格式化后的CSS文本
   * @remarks
   * 转换规则：
   * 1. 自动过滤无效条目（空选择器/属性/值）
   * 2. 可选保留原始数据中的元信息作为注释
   * 3. 对属性按字母顺序排序
   * 4. 支持强制!important标记
   * @example
   * // 基础用法
   * convertToCSS([{selector: '.btn', property: 'color', value: 'red'}])
   *
   * // 添加!important
   * convertToCSS(styles, { addImportant: true })
   *
   * // 禁用注释
   * convertToCSS(styles, { includeComments: false })
   */
  private convertToCSS(
    styles: AdjustElementStyleConfig[],
    options: ConvertCSSOptions = {},
  ): string {
    const {
      addImportant = false,
      includeComments = true,
      commentFormatter,
    } = options

    // 1. 转换对象结构
    const cssObj = styles.reduce((acc, style) => {
      if (!style.selector || !style.property || !style.value)
        return acc

      const selector = this.escapeSelector(style.selector.trim())
      const property = style.property.trim()
      let value = this.ensureSemicolon(style.value.trim())

      // 添加!important
      if (addImportant && !value.includes('!important')) {
        value = value.replace(/;?$/, ' !important;')
      }

      if (!acc[selector])
        acc[selector] = {}
      acc[selector][property] = value
      return acc
    }, {} as Record<string, Record<string, string>>)

    // 2. 格式化输出
    return Object.entries(cssObj)
      .map(([selector, properties]) => {
        const meta = includeComments
          ? styles.find(s => s.selector === selector)
          : null

        const comment = meta
          ? commentFormatter
            ? `/* ${commentFormatter(meta)} */\n` // 使用自定义格式化
            : `/* ${meta.name || meta.id} */\n` // 默认格式化
          : ''

        const props = this.sortCSSProperties(properties)
          .map(([prop, val]) => `  ${prop}: ${val}`)
          .join('\n')

        return `${comment}${selector} {\n${props}\n}`
      })
      .join('\n\n')
      .trim()
  }

  applyStyles(): void {
    if (!this.styles)
      return

    let styleContent = this.convertToCSS(this.styles, { addImportant: true })
    if (styleContent.length === 0)
      styleContent = '/* empty */'

    createStandardStyleTag(`${this.styleId}`, styleContent)
  }
}
